package user

import (
	"errors"
	"fmt"
	"log"

	"xorm.io/xorm"
)

func (msg *UsUser) QueryByName(db *xorm.Engine) error {
	var err error
	{
		_, err = db.Where(" user_name = ? ", msg.UserName).Get(msg)
		// _, err = db.SQL(" select t1.*, t2.id  from us_user t1 left join us_organization t2 on t1.user_name= t2.operator and t1.real_name=t2.operator_name where user_name = ? ", msg.UserName).Get(msg)
		if err != nil {
			log.Println("QueryByName[db.Get]:", err.Error())
			return err
		}
		// 获取UserId对应的生产组织
		err = db.SQL("select t2.* from us_user_organization t1, us_organization t2 where t1.org_id=t2.id and t1.user_id=(select user_name from us_user where user_name=?)", msg.UserName).Find(&msg.UserOrgs)
		if err != nil {
			log.Println("QueryByName[db.Get]:", err.Error())
			return err
		}
		err = db.SQL(" select t2.* from us_user_role t1,us_role t2 where t1.role_id = t2.id and t1.user_id = ? ", msg.Id).Find(&msg.Roles)
		if err != nil {
			log.Println("QueryByName[db.SQL]:", err.Error())
			return err
		}

	}
	return nil
}

func (msg *UsMenu) GetMenusByUserId(db *xorm.Engine, userId int64) error {
	err := db.SQL("SELECT DISTINCT t4.id,t4.NAME,t4.INDEX,t4.icon,t4.path,t4.pid,t4.create_time,t4.update_time,t4.type,t4.remarks FROM us_user_role t1 LEFT JOIN us_role t2 ON t1.role_id=t2.id LEFT JOIN us_role_menu t3 ON t2.id=t3.role_id LEFT JOIN us_menu t4 ON t3.menu_id=t4.id WHERE t1.user_id=? OR t4.NAME='快捷菜单' ORDER BY t4.INDEX", userId).Find(&msg.List)
	if err != nil {
		log.Println("GetMenusByUserId[db.SQL]:", err.Error())
		return err
	}
	for _, v := range msg.List {
		v.Open = false
		v.Selected = false
		v.Disabled = false
	}
	return nil
}

func (msg *UsMenu) GetUserMenusByUserId(db *xorm.Engine, userId int64) error {
	err := db.SQL("select t1.id,t1.name,t1.index,t1.icon,t1.path,t2.pid,t1.type from us_menu t1,us_user_menu t2 where t1.id = t2.menu_id and t2.user_id= ?", userId).Find(&msg.List)
	if err != nil {
		log.Println("GetUserMenusByUserId[db.SQL]:", err.Error())
		return err
	}
	for _, v := range msg.List {
		v.Open = false
		v.Selected = false
		v.Disabled = false
	}
	return nil
}

func (msg *UsUser) UpdUserOw(db *xorm.Engine) error {
	var err error
	tx := db.NewSession()
	defer tx.Close()
	err = tx.Begin()
	if err != nil {
		log.Println("UpdUser[tx.Begin]:", err.Error())
		return err
	}
	msg.Password = ""
	_, err = tx.Where("id=?", msg.Id).Update(msg)
	if err != nil {
		log.Println("UpdUser[tx.Update]:", err.Error())
		tx.Rollback()
		return err
	}
	_, err = tx.Exec("delete from us_user_role where user_id=?", msg.Id)
	if err != nil {
		log.Println("UpdUser[tx.Delete]:", err.Error())
		tx.Rollback()
		return err
	}
	for _, v := range msg.Roles {
		ur := &UsUserRole{UserId: msg.Id, RoleId: v.Id}
		_, err = tx.Insert(ur)
		if err != nil {
			log.Println("UpdUser[tx.Insert]:", err.Error())
			tx.Rollback()
			return err
		}
	}
	err = tx.Commit()
	if err != nil {
		log.Println("UpdUser[tx.Commit]:", err.Error())
		return err
	}
	return nil
}

func (msg *UsUser) AddUserOw(db *xorm.Engine) error {
	var err error
	tx := db.NewSession()
	defer tx.Close()
	err = tx.Begin()
	if err != nil {
		log.Println("AddUserOw[tx.Begin]:", err.Error())
		return err
	}
	_, err = tx.Insert(msg)
	if err != nil {
		tx.Rollback()
		return err
	}
	for _, obj0 := range msg.Roles {
		_, err = tx.Exec("insert into us_user_role (user_id,role_id) values (?,?)", msg.Id, obj0.Id)
		if err != nil {
			tx.Rollback()
			log.Println("AddUserOw[tx.Exec]:", err.Error())
			return err
		}
	}
	err = tx.Commit()
	if err != nil {
		log.Println("AddUserOw[tx.Commit]:", err.Error())
		return err
	}
	return nil
}

// func (msg *UsRole) GetRoleByName(db *xorm.Engine) error {
// 	var err error
// 	_, err = db.SQL("select * from us_role where name = ?", msg.Name).Get(msg)
// 	if err != nil {
// 		log.Println("GetRoleByName[db.SQL]:", err.Error())
// 		return err
// 	}
// 	return nil
// }

func (msg *UsRole) AddRoleOw(db *xorm.Engine) error {
	var err error
	tx := db.NewSession()
	defer tx.Close()
	err = tx.Begin()
	if err != nil {
		log.Println("AddRole[tx.Begin]:", err.Error())
		return err
	}
	{
		_, err = tx.Insert(msg)
		if err != nil {
			tx.Rollback()
			log.Println("AddRole[tx.Insert]:", err.Error())
			return err
		}
	}
	for _, obj0 := range msg.Menus {
		_, err = tx.Exec(" insert into us_role_menu (role_id,menu_id,create_time) values (?,?,now())", msg.Id, obj0.Id)
		if err != nil {
			tx.Rollback()
			log.Println("AddRole[tx.Exec]:", err.Error())
			return err
		}
	}

	err = tx.Commit()
	if err != nil {
		log.Println("AddRole[tx.Commit]:", err.Error())
		return err
	}

	return nil
}

func (msg *UsRole) UpdRoleOw(db *xorm.Engine) error {
	var err error
	tx := db.NewSession()
	defer tx.Close()
	err = tx.Begin()
	if err != nil {
		log.Println("UpdRoleOw[tx.Begin]:", err.Error())
		return err
	}
	_, err = tx.Where("id=?", msg.Id).Update(msg)
	if err != nil {
		log.Println("UpdRoleOw[tx.Update]:", err.Error())
		tx.Rollback()
		return err
	}

	_, err = tx.Exec("delete from us_role_menu where role_id=?", msg.Id)
	if err != nil {
		log.Println("UpdRoleOw[tx.Delete]:", err.Error())
		tx.Rollback()
		return err
	}
	if len(msg.Menus) > 0 {
		tmpRoleMenuList := make([]*UsRoleMenu, 0)
		for _, v := range msg.Menus {
			if msg.Id > 0 && v.Id > 0 {
				roleMenu := &UsRoleMenu{RoleId: msg.Id, MenuId: v.Id, MenuAction: v.MenuAction}
				tmpRoleMenuList = append(tmpRoleMenuList, roleMenu)
			}
		}
		_, err = tx.Insert(tmpRoleMenuList)
		if err != nil {
			log.Println("UpdRoleOw[tx.Insert]:", err.Error())
			tx.Rollback()
			return err
		}
	}
	err = tx.Commit()
	if err != nil {
		log.Println("UpdRoleOw[tx.Commit]:", err.Error())
		return err
	}
	return nil
}

func (msg *UsRole) GetMenusByRoleId(db *xorm.Engine) error {
	var err error
	err = db.SQL(" select t1.id,t1.name,t1.index,t1.icon,t1.path,t1.type,t1.remarks,t2.menu_action from us_menu t1,us_role_menu t2 where t1.id = t2.menu_id and t2.role_id=?", msg.Id).Find(&msg.Menus)
	if err != nil {
		log.Println("GetMenusByRoleId[db.SQL]:", err.Error())
		return err
	}
	return nil
}

func (msg *UsMenu) CountMenuByPid(db *xorm.Engine) (int, error) {
	var err error
	var count int
	_, err = db.SQL("select count(1) as count from us_menu where pid = ?", msg.Id).Get(&count)
	if err != nil {
		log.Println("CountMenuByPid[db.SQL]:", err.Error())
		return 0, err
	}
	return count, nil
}

func (msg *UsOrganization) CountOrganization(db *xorm.Engine) (int, error) {
	var err error
	var count int
	prm := make([]interface{}, 0)
	prm = append(prm, msg.Code)
	prm = append(prm, msg.Name)
	sql := "select count(1) from us_organization where (code = ? or name = ?)"
	if msg.Id > 0 {
		sql += " and id != ?"
		prm = append(prm, msg.Id)
	}
	_, err = db.SQL(sql, prm...).Get(&count)
	if err != nil {
		log.Println("OrganizationExist[db.SQL]:", err.Error())
		return count, err
	}
	return count, nil
}

func (msg *UsOrganization) GetOrganizationIdByName(db *xorm.Engine) error {
	var err error
	_, err = db.Where("name = ? ", msg.Name).Get(msg)
	if err != nil {
		log.Println("GetOrganizationIdByName[db.Get]:", err.Error())
		return err
	}
	return nil
}

func (msg *UsMenu) addMenu(tx *xorm.Session) error {
	var err error
	{
		_, err = tx.Insert(msg)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	return nil
}

func (msg *UsMenu) updMenu(tx *xorm.Session) error {
	var err error
	_ = err
	if msg.Id == 0 {
		return fmt.Errorf("缺少参数")
	}
	{
		_, err = tx.Exec(" update us_menu set name = ?,`index` = ?,icon = ?,path = ?,pid = ?,type = ?,remarks = ?,update_time = now() where id = ?", msg.Name, msg.Index, msg.Icon, msg.Path, msg.Pid, msg.Type, msg.Remarks, msg.Id)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	return nil
}

func (msg *UsMenuAction) getMenuAction(db *xorm.Engine) error {
	var err error
	_ = err
	{
		err = db.Find(&msg.List)
		if err != nil {
			log.Println("GetMenuAction[db.Find]:", err.Error())
			return err
		}
	}
	return nil
}

func (msg *UsMenu) addMenuActions(tx *xorm.Session) error {
	var err error
	if len(msg.ActionList) > 0 {
		_, err = tx.Insert(msg.ActionList)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	return nil
}

func (msg *UsMenu) delMenuActions(tx *xorm.Session) error {
	var err error
	if msg.Id == 0 {
		return fmt.Errorf("缺少参数")
	}
	{
		_, err = tx.Exec("delete from us_menu_action where menu_id = ?", msg.Id)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	return nil
}

func (msg *UsRoleMenu) GetRoleMenuByUserId(userId int64, db *xorm.Engine) error {
	var err error
	err = db.SQL("	select * from us_role_menu  where role_id  in (	select role_id from us_user_role where user_id = ?)", userId).Find(&msg.List)
	if err != nil {
		return err
	}
	return nil
}

func (msg *UsUser) GetUserByName(db *xorm.Engine) error {
	var err error
	{
		sql := ""
		prm := make([]interface{}, 0)
		var val interface{}
		_ = val
		prm = append(prm, msg.UserName)
		sql += " " + "select t1.id,t1.user_name,t1.real_name,t1.`password`,t1.`status`,t2.org_id as org_id from us_user t1 left join us_user_organization t2 on t1.user_name = t2.user_id  where t1.user_name= ? "
		val = msg.Id
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + " and t1.id!=?"
		}
		_, err = db.SQL(sql, prm...).Get(msg)
		if err != nil {
			log.Println("GetUserByName[db.SQL]:", err.Error())
			return err
		}
	}
	{
		err = db.SQL(" select t2.* from us_user_role t1,us_role t2 where t1.role_id = t2.id and t1.user_id = ? ", msg.Id).Find(&msg.Roles)
		if err != nil {
			log.Println("GetUserByName[db.SQL]:", err.Error())
			return err
		}
	}
	{
		positionCode := ""
		_, err = db.SQL(" select position_code from qa_staff where work_code = ? and position_code like 'PK%' limit  1", msg.UserName).Get(&positionCode)
		if err != nil {
			log.Println("GetUserByName[db.SQL]:", err.Error())
			return err
		}
		if positionCode != "" && positionCode[:2] == "PK" {
			msg.QaFlag = 1
		} else {
			msg.QaFlag = 2
		}
		if msg.UserName == "admin" {
			msg.QaFlag = 1
		}
	}
	return nil
}

func (msg *UsOrganization) GetOrganizationU9Code(db *xorm.Engine) error {
	var err error
	err = db.SQL("select id,name,org_code from us_organization where org_code is not null").Find(&msg.List)
	if err != nil {
		log.Println("GetOrganizationU9Code[db.SQL]:", err.Error())
		return err
	}
	return nil
}

func (msg *UsOrganization) GetUsOrganizationTree(db *xorm.Engine) error {
	var err error
	_ = err
	{
		sql := ""
		prm := make([]interface{}, 0)
		var val interface{}
		_ = val
		sql += " " + "1=1"
		val = msg.Code
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + "and code=?"
		}
		val = "%" + msg.Name + "%"
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + "and name like ?"
		}
		val = "%" + msg.Operator + "%"
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + "and operator like ?"
		}
		val = "%" + msg.OperatorName + "%"
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + "and operator_name like ?"
		}
		err = db.Where(sql, prm...).Find(&msg.List)
		if err != nil {
			log.Println("GetUsOrganizationList[db.Find]:", err.Error())
			return err
		}
	}
	{
		obj0 := msg.Count
		_ = obj0
		sql := ""
		prm := make([]interface{}, 0)
		var val interface{}
		_ = val
		sql += " " + "select count(1) as count from us_organization where 1=1"
		val = msg.Code
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + "and code=?"
		}
		val = "%" + msg.Name + "%"
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + " and name like ?"
		}
		val = "%" + msg.Operator + "%"
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + "and operator like ?"
		}
		val = "%" + msg.OperatorName + "%"
		if !(val == 0 || val == "" || val == 0.0 || val == "%%" || val == "%" || val == int32(0) || val == int64(0) || val == int16(0) || val == float32(0.0) || val == false) {
			prm = append(prm, val)
			sql += " " + "and operator_name like ?"
		}
		_, err = db.SQL(sql, prm...).Get(&msg.Count)
		if err != nil {
			log.Println("GetUsOrganizationList[db.SQL]:", err.Error())
			return err
		}
	}
	return nil
}

// 组织现在是嵌套结构，需要获取组织tree，给前端
func (msg *UsOrganization) getUsOrgTree(db *xorm.Engine) error {
	// 第一级是pid为0的一级组织
	sql := "select * from us_organization where pid=0"
	err := db.SQL(sql).Find(&msg.List)
	if err != nil {
		return errors.New("获取组织tree失败：" + err.Error())
	}
	// 然后开始递归查询，直到children的数量为0
	err = getUsOrgChildren(msg.List, db)
	if err != nil {
		return err
	}

	return nil
}

func getUsOrgChildren(list []*UsOrganization, db *xorm.Engine) error {
	if len(list) == 0 {
		return nil
	}
	for _, org := range list {
		err := db.SQL("select * from us_organization where pid=?", org.Id).Find(&org.Children)
		if err != nil {
			return errors.New("获取组织children失败：" + err.Error())
		}
		err = getUsOrgChildren(org.Children, db)
		if err != nil {
			return errors.New("获取组织children失败：" + err.Error())
		}
	}
	return nil
}

// 更新用户电子签章URL
func (msg *UsUser) UpdateSignatureURL(db *xorm.Engine, signatureURL string) error {
	msg.SignUrl = signatureURL
	_, err := db.Where("user_name=?", msg.UserName).Cols("sign_url").Update(msg)
	if err != nil {
		log.Println("UpdateSignatureURL[db.Update]:", err.Error())
		return err
	}
	return nil
}

// 获取用户电子签章URL
func (msg *UsUser) GetSignatureURL(db *xorm.Engine) (string, error) {
	has, err := db.Where("user_name=?", msg.UserName).Cols("sign_url").Get(msg)
	if err != nil {
		log.Println("GetSignatureURL[db.Get]:", err.Error())
		return "", err
	}
	if !has {
		return "", errors.New("用户不存在")
	}
	return msg.SignUrl, nil
}
